package com.wdl.webserver.api;

import javax.annotation.PostConstruct;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.wdl.webserver.data.GenResponse;

import springfox.documentation.annotations.ApiIgnore;

@RestController
@RequestMapping("/api/sms")
public class SmsService {
    private static final Logger LOG = LoggerFactory.getLogger(SmsService.class);

    @Value("${sms.AccessKeyID}")
    String accessKeyId;

    @Value("${sms.AccessKeySecret}")
    String accessKeySecret;

    @Value("${sms.templateCode}")
    String templateCode;

    @Value("${sms.intl.templateCode}")
    String intlTemplateCode;

    @Value("${sms.signName}")
    String signName;

    @Autowired
    CacheService cacheService;

    private final String product = "Dysmsapi";
    private final String domain = "dysmsapi.aliyuncs.com";

    private IAcsClient acsClient;

    @ApiIgnore
    @PostMapping(value = "/wdlCodeWxshtuiuykdkdkdppwee", produces = MediaType.APPLICATION_JSON)
    public GenResponse sendSms(@RequestParam("phoneNumber") String phoneNumber, @RequestParam("language") String language) {
        LOG.info("Received get code request for " + phoneNumber);

        GenResponse response = new GenResponse();
        response.setStatus(Status.NOT_FOUND.getStatusCode());
        response.setStatusInfo(Status.NOT_FOUND);

        if (phoneNumber == null || phoneNumber.trim().isEmpty()) {
            response.setInfo("emptyPhoneNumber");
            return response;
        }

        int number = (int) ((Math.random()*9+1)*1000);
        SendSmsRequest request = new SendSmsRequest();
        request.setMethod(MethodType.POST);
        request.setSignName(signName);

        if (phoneNumber.startsWith("0")) {
            LOG.info("Got request for phone number: " + phoneNumber + ", intlTempalteCode=" + intlTemplateCode);
            request.setPhoneNumbers(phoneNumber.substring(1));
            request.setTemplateCode(intlTemplateCode);
        } else {
            LOG.info("Got request for phone number: " + phoneNumber + ", tempalteCode=" + templateCode);
            request.setPhoneNumbers(phoneNumber);
            request.setTemplateCode(templateCode);
        }

        request.setTemplateParam("{\"code\":\"" + number + "\"}");
        LOG.debug("Got radom number: " + number);

        SendSmsResponse sendSmsResponse;
        try {
            LOG.debug("Sending code request for " + phoneNumber);
            sendSmsResponse = acsClient.getAcsResponse(request);
            LOG.debug("Sent code request for " + phoneNumber + ", code=" + sendSmsResponse.getCode());
            response.setInfo(sendSmsResponse.getCode() == null ? "" : sendSmsResponse.getCode());
            if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
                response.setStatus(Status.OK.getStatusCode());
                response.setStatusInfo(Status.OK);
                cacheService.updateCode(phoneNumber, String.valueOf(number));
            }
        } catch (Exception e) {
            LOG.error("Failed to get SMS code.", e);
        }

        return response;
    }

    @PostConstruct
    private void initSmsService() {
        LOG.info("Init SmsService with cn-hangzhou");
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);

        try {
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        } catch (ClientException e) {
            LOG.error("Failed to add endpoint for sms service.", e);
        }

        acsClient = new DefaultAcsClient(profile);
    }
}
